﻿using System;
using System.Configuration;
using System.Web;
using Medianamik.Core;
using Medianamik.Core.Bootstrapping;
using Medianamik.Core.Configuration;

namespace Medianamik.Client
{
    // TODO: Trouver une façon élégante de permettre à un programmeur d'ajouter de la logique personnalisée à l'application
    public class MedianamikApplication : HttpApplication
    {
        protected void Application_BeginRequest(object sender, EventArgs e)
        {
            Bootstrapper.GetBootstrapper().SafeConfigure(this);
        }

        protected void Application_End(object sender, EventArgs e)
        {
            Bootstrapper.GetBootstrapper().Cleanup(this);
        }

        private static readonly MedianamikConfigSection _config = (MedianamikConfigSection)ConfigurationManager.GetSection(ConfigurationSectionName.MEDIANAMIK);

        protected void Application_Error(object sender, EventArgs e)
        {
            //S'assurer que ce n'est pas une erreur en boucle.
            var isGeneralError = false;
            if (Application["SentInLastMinute"] != null)
            {
                var lastError = (DateTime)Application["LastError"];
                var diff = DateTime.Now.Subtract(lastError);

                if (diff.Minutes < 1)
                {
                    var numberOfMessage = (int)Application["SentInLastMinute"];
                    numberOfMessage++;
                    Application["SentInLastMinute"] = numberOfMessage;

                    //Tolérance de 10 erreurs consécutives dans la dernière minute
                    if (numberOfMessage > 10)
                    {
                        isGeneralError = true; // La gestion des erreurs est désactivée.

                        //Erreur en boucle. Envoyer un avertissement à tous les 100 messages.
                        if (_config.ErrorManagement && numberOfMessage % 100 == 0)
                        {
                            new Utility().GetGlobalLogger().Fatal("Erreur non prise en charge", Server.GetLastError());
                        }
                    }
                }
                else
                {
                    //Il n'y a pas eu d'autres erreur dans la dernière minute, réinitialiser les compteurs
                    Application["SentInLastMinute"] = 1;
                    Application["LastError"] = DateTime.Now;
                }
            }
            else
            {
                //C'est la permière fois
                Application.Add("SentInLastMinute", 1);
                Application.Add("LastError", DateTime.Now);
            }

            //Traitement de l'erreur
            if (_config.ErrorManagement && !isGeneralError)
            {
                if (Context.Error.GetBaseException().GetType().ToString() == typeof(System.Data.SqlClient.SqlException).ToString())
                {
                    new Utility().GetGlobalLogger().Fatal("Erreur non prise en charge", Server.GetLastError());
                    Response.Redirect("/errors/error.html");
                }

                else
                {
                    var httpError = (HttpException)(Context.Error);
                    if (((Context.Error).GetType().ToString() != typeof(HttpException).ToString()) ||
                         (httpError.GetHttpCode()) != 404 && ((Context.Error).GetType().ToString() != typeof(HttpException).ToString()))
                    {
                        new Utility().GetGlobalLogger().Fatal("Erreur non prise en charge", Server.GetLastError());
                    }
                }


            }
            else
                if (isGeneralError)
                    Response.Redirect("/errors/error.html"); //La gestion d'erreur est désactivée.

        }

    }
}
